import itertools
import random
import re
from itertools import combinations
from collections import defaultdict, OrderedDict, Counter

class Team:
    def __init__(self, name):
        self.name = name
        self.points = 0  # 大分
        self.small = 0   # 小分
        self.win_loss = {}  # 记录与其他队伍的胜负关系 {对手名字: 'win'/'loss'}

    def add_result(self, opponent, points, opponent_points):
        self.win_loss[opponent] = 'win' if points > opponent_points else 'loss'

class Match:
    def __init__(self, team1, team2):
        self.team1 = team1
        self.team2 = team2
        self.result = None  # 格式为 (team1_score, team2_score)
        self.id = None  # 唯一标识符

    def simulate_game(self):
        # 模拟每局比赛，直到一方先得3分
        score1 = 0
        score2 = 0
        while score1 < 3 and score2 < 3:
            # 每局胜负概率50%
            if random.random() < 0.5:
                score1 += 1
            else:
                score2 += 1
        return (score1, score2)

def rank_teams(team, other_teams):
    # 统计该队在该组内胜负关系的分值
    score = 0
    for t in other_teams:
        if t.name == team.name:
            continue
        res = team.win_loss.get(t.name, 'loss')
        if res == 'win':
            score += 1
        else:
            score -= 1
    return score

def main():
    global team_names
    # 用户输入队伍名字
    while True:
        input_names = input("请输入六个队伍的名字，用空格分隔（2-5个字母）：").split()
        if len(input_names) != 6:
            print("请输入六个队伍的名字！")
            continue
        # 检查每个队伍名字的长度
        valid = True
        for name in input_names:
            if not (2 <= len(name) <=5) or not name.isalpha():
                valid = False
                print(f"队伍名字 '{name}' 不符合要求，请输入2-5个字母的名字。")
                break
        if valid:
            team_names = input_names
            break

    # 初始化队伍
    teams = {name: Team(name) for name in team_names}
    # 初始化所有匹配，使用 itertools.combinations 生成所有组合
    from itertools import combinations
    all_matches = []
    for team1, team2 in combinations(teams.values(), 2):
        all_matches.append(Match(team1, team2))

    # 获取用户输入
    user_input = input("请输入所有已完成场次，格式如 ag2es3（队伍名可以是2-5个字母）：").strip()
    completed_matches = user_input.split()

    # 解析已完成场次
    for match_str in completed_matches:
        # 使用正则表达式解析格式，例如：ag2es3 或 as2be3
        # 假设格式为 队伍名1得分队伍名2得分，例如 'ag2es3' 表示 ag和es对战，ag得2分，es得3分
        # 正则表达式匹配两个队伍名和两个数字
        match = re.match(r'^([a-zA-Z]{2,5})(\d+)([a-zA-Z]{2,5})(\d+)$', match_str)
        if not match:
            print(f"警告：非法场次格式 '{match_str}'，应格式为 队伍1得分z队伍2得分，例如 ag2es3。")
            continue
        x = match.group(1)
        y = int(match.group(2))
        z = match.group(3)
        w = int(match.group(4))
        
        # 查找对应的 Match 对象
        found = False
        for match_obj in all_matches:
            # 检查队伍是否匹配
            if (match_obj.team1.name == x and match_obj.team2.name == z) or \
               (match_obj.team1.name == z and match_obj.team2.name == x):
                # 确定队伍顺序
                if match_obj.team1.name == x and match_obj.team2.name == z:
                    result = (y, w)
                else:
                    result = (w, y)
                match_obj.result = result
                found = True
                break
        if not found:
            print(f"警告：未找到对战 {x} vs {z} 的比赛对象，可能未生成或名称错误。")

    # 更新队伍的初始得分
    for match in all_matches:
        if match.result:
            t1 = match.team1
            t2 = match.team2
            points1, points2 = match.result
            # 更新大分和小分
            if points1 > points2:
                t1.points += 1
                t1.small += (points1 - points2)
                t2.small -= (points1 - points2)
            else:
                t2.points += 1
                t2.small += (points2 - points1)
                t1.small -= (points2 - points1)
            # 更新胜负关系
            t1.add_result(t2.name, points1, points2)
            t2.add_result(t1.name, points2, points1)

    # 剩余比赛是所有未完成的比赛
    remaining_matches = [match for match in all_matches if not match.result]

    # 为剩余比赛生成唯一的标识符
    for i, match in enumerate(remaining_matches):
        match.id = f"match_{i+1}"

    # 进行蒙特卡洛模拟
    iterations = 10000  # 模拟次数
    count_rank = {name: [0] * 7 for name in team_names}  # 记录每个队伍在每个排名的次数
    future_scores = {name: defaultdict(lambda: defaultdict(list)) for name in team_names}  # 记录未来可能的得分及其对应的剩余场次战果

    # 用于模拟
    current_teams = {t.name: t for t in teams.values()}

    for _ in range(iterations):
        # 复制当前队伍状态
        new_teams = {name: Team(name) for name in team_names}
        for team in new_teams.values():
            orig_team = current_teams[team.name]
            team.points = orig_team.points
            team.small = orig_team.small
            team.win_loss = orig_team.win_loss.copy()

        # 模拟剩余比赛
        current_remaining_results = OrderedDict()
        for match in remaining_matches:
            t1 = new_teams[match.team1.name]
            t2 = new_teams[match.team2.name]
            result = match.simulate_game()  # 模拟比赛
            current_remaining_results[match.id] = (match.team1.name, match.team2.name, result[0], result[1])

            # 更新大分和小分
            if result[0] > result[1]:
                t1.points += 1
                t1.small += (result[0] - result[1])
                t2.small -= (result[0] - result[1])
            else:
                t2.points += 1
                t2.small += (result[1] - result[0])
                t1.small -= (result[1] - result[0])

            # 更新胜负关系
            t1.add_result(t2.name, result[0], result[1])
            t2.add_result(t1.name, result[1], result[0])

        # 将 current_remaining_results 转换为元组
        current_remaining_results_key = tuple(current_remaining_results.items())

        # 生成积分榜
        ranking = sorted(new_teams.values(), key=lambda x: (-x.points, -x.small))
        # 处理大小分相同的情况
        i = 0
        while i < len(ranking):
            j = i + 1
            while j < len(ranking) and ranking[j].points == ranking[i].points and \
                  ranking[j].small == ranking[i].small:
                j += 1
            # 当前组是i到j-1
            group = ranking[i:j]
            # 处理组内胜负关系
            group = sorted(group, key=lambda x: rank_teams(x, group), reverse=True)
            # 查看是否是三个队伍分数一致且胜负关系循环
            if len(group) == 3:
                # 检查胜负关系是否循环
                a, b, c = group
                ab = a.win_loss.get(b.name, 'loss')
                bc = b.win_loss.get(c.name, 'loss')
                ca = c.win_loss.get(a.name, 'loss')
                if (ab == 'win' and bc == 'win' and ca == 'win') or (ab == 'loss' and bc == 'loss' and ca == 'loss'):
                    # 存在循环胜负关系
                    print(f"注意：队伍 {a.name}, {b.name}, {c.name} 可能形成循环胜负关系，需加赛！")
                    # 输出相关信息
                    print(f"    大分: {a.points}, 小分: {a.small}")
            # 替换原位置
            ranking[i:j] = group
            i = j

        # 计算每个队伍的排名和未来得分
        for rank, team in enumerate(ranking, 1):
            count_rank[team.name][rank] += 1
            # 使用元组作为键存储未来得分及其对应的剩余场次战果
            future_scores[team.name][(team.points, team.small)][rank].append(current_remaining_results_key)

    # 计算概率
    rank_prob = {name: [count / iterations for count in count_rank[name]] for name in team_names}

    # 输出6x6的表格
    header = "队伍/排名"
    print("{: <10}{}".format(header, ''.join([f"{i + 1: >8}" for i in range(6)])))
    for name in team_names:
        probabilities = []
        for rank in range(1, 7):
            prob = rank_prob[name][rank]
            probabilities.append(f"{prob * 100:.2f}%")
        print("{: <15}{}".format(name, '   '.join(probabilities)))

    # 等待用户输入指定队伍和名次
    while True:
        user_input = input("请输入要查询的队伍和名次，格式如 ag 1 2（输入 'exit' 退出）：").strip()
        if user_input.lower() == 'exit':
            break
        parts = user_input.split()
        if len(parts) < 2:
            print("请输入有效的队伍和名次！")
            continue
        target_team = parts[0]
        target_ranks = []
        try:
            target_ranks = [int(rank) for rank in parts[1:]]
        except:
            print("请输入有效的名次数字！")
            continue
        if target_team not in team_names:
            print(f"队伍 '{target_team}' 不存在！")
            continue

        # 查找对应排名的未来得分情况
        ranking_data = defaultdict(list)
        for (p, s), rank_dict in future_scores[target_team].items():
            for rank, results in rank_dict.items():
                if rank in target_ranks:
                    # 将结果合并
                    for result_key in results:
                        ranking_data[result_key].append((p, s, rank))
        
        print(f"队伍 {target_team} 在排名 {target_ranks} 的情况下，对应的剩余场次战果：")
        if ranking_data:
            for result_key, data in ranking_data.items():
                p, s, rank = data[0]
                formatted_results = []
                # 将 result_key 转换回 OrderedDict
                result_od = OrderedDict(result_key)
                for k, v in result_od.items():
                    team1, team2, score1, score2 = v
                    formatted_results.append(f"{team1}{score1}{team2}{score2}")
                print(f"    排名: {rank}, 大分: {p}, 小分: {s}, 剩余场次战果: {' '.join(formatted_results)}")
        else:
            print(f"    队伍 {target_team} 在排名 {target_ranks} 的情况下，没有数据。")

if __name__ == "__main__":
    team_names = None
    main()